#include "vectorD.h"
#include "randUtil.h"

unsigned int VectorD::DIMENSIONS = 2;

VectorD::VectorD()
{
	elements_.resize(DIMENSIONS);
}

DATA_TYPE VectorD::getSquaredNorm() const
{
	DATA_TYPE sqNorm = 0;
	for (unsigned int i = 0; i < VectorD::DIMENSIONS; ++i)
	{
		sqNorm += elements_[i] * elements_[i];
	}
	return sqNorm;
}

DATA_TYPE VectorD::normalize()
{
	DATA_TYPE norm = sqrt(getSquaredNorm());
	if (norm > 0)
	{
		for (unsigned int i = 0; i < VectorD::DIMENSIONS; ++i)
		{
			elements_[i] /= norm;
		}
	}

	return norm;
}

VectorD VectorD::gaussianRandomVector()
{
	VectorD ret;
	for (unsigned int i = 0; i < VectorD::DIMENSIONS; i += 2)
	{
		DATA_TYPE v0, v1;
		v0 = RandUtil::randGaussian(v1);
		ret.elements_[i] = v0;
		if (i + 1 < VectorD::DIMENSIONS)
			ret.elements_[i + 1] = v1;
	}
	return ret;
}

VectorD VectorD::operator+(const VectorD& rhs) const
{
	VectorD ret;
	for (unsigned int i = 0; i < VectorD::DIMENSIONS; ++i)
	{
		ret.elements_[i] = elements_[i] + rhs.elements_[i];
	}
	return ret;
}

VectorD VectorD::operator-(const VectorD& rhs) const
{
	VectorD ret;
	for (unsigned int i = 0; i < VectorD::DIMENSIONS; ++i)
	{
		ret.elements_[i] = elements_[i] - rhs.elements_[i];
	}
	return ret;
}

DATA_TYPE operator*(const VectorD& lhs, const VectorD& rhs)
{
	DATA_TYPE dot = 0;
	for (unsigned int i = 0; i < VectorD::getDimensions(); ++i)
	{
		dot += lhs[i] * rhs[i];
	}
	return dot;
}

VectorD operator*(DATA_TYPE lhs, const VectorD& rhs)
{
	VectorD ret;
	for (unsigned int i = 0; i < VectorD::getDimensions(); ++i)
	{
		ret[i] = lhs * rhs[i];
	}
	return ret;
}